package com.ccx.coachsite.versionupdate;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.ccx.coachsite.data.SystemConst;
import com.ccx.coachsite.util.SUtil;

public class SoftUpdateDownloadThread extends Thread {
	
	/**
	 * 开始下载消息码
	 */
	public final static int MSG_CODE_DOWNLOAD_START = 1003;
	
	/**
	 * 下载失败消息码
	 */
	public final static int MSG_CODE_DOWNLOAD_FAILED = 1000;
	
	/**
	 * 下载成功消息码
	 */
	public final static int MSG_CODE_DOWNLOAD_SUCCESS = 1001;
	
	/**
	 * 下载中消息码
	 */
	public final static int MSG_CODE_DOWNLOADING = 1002;
	
	private final static String TAG = "SoftUpdateDownloadThread";
	
	/**
	 * 停止下载标志
	 */
	private boolean stopFlag = true;
	
    private static int BUFFER_SIZE = 1024; // 缓冲区大小
	
    
    private Handler handler;
    
    private String downloadUrl;
    
    private String saveFileName;
    
    public SoftUpdateDownloadThread(Handler mhandler, String url, String saveFileName){
		handler = mhandler;
		downloadUrl = url;
		this.saveFileName = saveFileName;
	}
	
	public void start(){
		stopFlag = false;
		SystemConst.createDefaultDir();
		super.start();
	}
	
	public void run(){
		
		if(null == downloadUrl)return;
		
		String filePath = SystemConst.BASE_DIR + "/" + saveFileName + ".apk";
		
		Log.d(TAG, "downloadFile:" + downloadUrl);

        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        byte[] buf = new byte[BUFFER_SIZE];
        int size = 0;
        long downloadSize = 0;
        
        //需要跳转的地址
        if (downloadUrl.contains(".aspx")) {
			try {
				HttpParams params = new BasicHttpParams();
				// 设置连接超时和 Socket 超时，以及 Socket 缓存大小
				HttpConnectionParams.setConnectionTimeout(params, 4 * 1000);
				HttpConnectionParams.setSoTimeout(params, 4 * 1000);
				HttpConnectionParams.setSocketBufferSize(params, 8192);
				// 设置重定向，缺省为 true
				HttpClientParams.setRedirecting(params, false);
				HttpClient client = new DefaultHttpClient(params);
				downloadUrl = downloadUrl.replaceAll(" ", "%20");
				HttpGet request = new HttpGet(downloadUrl);
				HttpResponse response = client.execute(request);
				Header head = response.getFirstHeader("Location");
				if (head != null) {				
					downloadUrl = head.getValue();
				}
				Log.d(TAG, "down load filePath="+filePath);
			} catch (Exception e) {
				Log.e(TAG, "HttpClient redirect error, Exception:" + e);
				//下载失败
				handler.obtainMessage(MSG_CODE_DOWNLOAD_FAILED).sendToTarget();
			} 
		}

        String tempFilePath = null;
        
        try {
            // 建立链接
            url = new URL(SUtil.Utf8URLencode(downloadUrl));
            httpUrl = (HttpURLConnection) url.openConnection();
            // 连接指定的资源
            httpUrl.connect();
            // 获取网络输入流
            bis = new BufferedInputStream(httpUrl.getInputStream());
            // 建立文件
            File file = new File(filePath);
            // 建立下载临时文件
            tempFilePath = filePath +".temp";
            fos = new FileOutputStream(tempFilePath);
            //获取文件长度
            long fileSize = httpUrl.getContentLength();
            //开始下载
            Bundle b = new Bundle();
			b.putLong("fileSize", fileSize);
			Message msg = handler.obtainMessage(MSG_CODE_DOWNLOAD_START);
			msg.setData(b);
			msg.sendToTarget();
            
            // 保存文件
            while ((size = bis.read(buf)) != -1) {
            	if(stopFlag){//取消下载
            		fos.close();
                    bis.close();
                    if (httpUrl != null) {
                        httpUrl.disconnect();
                    }
                    return;
            	}
                fos.write(buf, 0, size);
                downloadSize += size;
                
                Bundle bundle = new Bundle();
				bundle.putLong("downloadedSize", downloadSize);
				bundle.putLong("fileSize", fileSize);
				Message message = handler.obtainMessage(MSG_CODE_DOWNLOADING);
				message.setData(bundle);
				message.sendToTarget();
            }
            fos.close();
            bis.close();
            
            File tempFile = new File(tempFilePath);
            
            RandomAccessFile randomFile = new RandomAccessFile(tempFile, "rw");
            long length = randomFile.length();
            if(length<1024*10)
            	throw new Exception();
            	
            tempFile.renameTo(file);
            
            //下载成功
            handler.obtainMessage(MSG_CODE_DOWNLOAD_SUCCESS).sendToTarget();
        } catch (Exception e) {
        	if(tempFilePath!=null&&new File(tempFilePath).exists()){
        		new File(tempFilePath).delete();
        	}
            Log.e(TAG, "downfile:" + downloadUrl + ",Exception:" + e);
            //下载失败
			handler.obtainMessage(MSG_CODE_DOWNLOAD_FAILED).sendToTarget();
        } finally {
            if (httpUrl != null) {
                httpUrl.disconnect();
            }
        }
	}
	
	/**
	 * <br>Description: 取消下载，删除临时文件
	 * @see java.lang.Thread#interrupt()
	 */
	@Override
	public void interrupt() {
		super.interrupt();
		
		stopFlag = true;
		String tempFilePath = SystemConst.BASE_DIR + "/" + saveFileName + ".apk.temp";
		if(tempFilePath!=null && new File(tempFilePath).exists()){
    		new File(tempFilePath).delete();
    	}
		
        Log.d(TAG, "downfile cancelled..");
	}
	
}
